﻿//This file is part of Search Engine by Tomasz Kusienicki.
// 
//This Search Engine is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//any later version.
// 
//Foobar is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
// 
//You should have received a copy of the GNU General Public License
//on <http://www.gnu.org/licenses/>.

using System;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using AdminApp1.Common;
using AdminApp1.Models;
using AdminApp1.Views;

namespace AdminApp1.Presenters
{
    public class BusStopPresenter : PresenterBase<BusStopView, BusStopPresenter, BusStopModel>
    {

        #region variables
        private SearchEngineDatabaseDataContext _dc;
        #endregion

        #region Constructor
        public BusStopPresenter(BusStopView view, BusStopModel model, SearchEngineDatabaseDataContext searchEngineDatabaseDataContext) 
            : base(view, model)
        {
            Model.MaxWidth = 800;
            Model.MaxHeight = 500;
            _dc = searchEngineDatabaseDataContext;
            LoadData();
            AdjustTableSize();
        }
        #endregion


        #region LoadData
        private void LoadData()
        {
            try {
                var q = from a in _dc.GetTable<BusStop>() select a;
                View.dataGridView1.DataSource = q;
            }
            catch (SqlException)
            {
                MessageBox.Show(@"Database is not valid", @"SqlException", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        #endregion

        #region AdjustTableSize
        private void AdjustTableSize()
        {
            var preferredWidth = View.dataGridView1.PreferredSize.Width;
            var preferredHeight = View.dataGridView1.PreferredSize.Height;
            var newSize = new Size
            {
                Width = Model.MaxWidth > preferredWidth ? preferredWidth : Model.MaxWidth,
                Height = Model.MaxHeight > preferredHeight ? preferredHeight : Model.MaxHeight
            };
            View.Size = newSize;
        }
        #endregion

        #region HandleOnClosed, UpdateException
        public void HandleOnClosed()
        {
            Cursor.Current = Cursors.WaitCursor;
            var name = View.Text;
            var all = View.dataGridView1.Rows.Count-1;            
            for (var i = 0; i < View.dataGridView1.Rows.Count-1; i++)
            {
                View.Text = string.Format("{0} - {1}/{2}", name, i, all);

                try
                {
                    HandleInsertOrUpdate(
                        View.dataGridView1.Rows[i].Cells[0].Value.ToString(),
                        View.dataGridView1.Rows[i].Cells[1].Value.ToString(),
                        View.dataGridView1.Rows[i].Cells[2].Value.ToString(),
                        View.dataGridView1.Rows[i].Cells[3].Value.ToString(),
                        View.dataGridView1.Rows[i].Cells[4].Value.ToString(),
                        View.dataGridView1.Rows[i].Cells[5].Value.ToString());
                }
                catch (NullReferenceException)
                {
                    UpdateException();
                    View.Text = name;
                    return;
                }
                catch (InvalidOperationException)
                {
                    UpdateException();
                    View.Text = name;
                    return;
                }
                catch (SqlException)
                {
                    UpdateException();
                    View.Text = name;
                    return;
                }
            }
            View.Text = name;
            View.Hide();
        }

        private void UpdateException()
        {
            if (MessageBox.Show(@"Database could not be updated. Check data store integrity and fill the non-nullable columns. " +
                @"Please contact the administrator if this problem persists.", @"SqlException",
                MessageBoxButtons.OKCancel, MessageBoxIcon.Error) == DialogResult.Cancel)
            {
                _dc = new SearchEngineDatabaseDataContext();
                LoadData();
                View.Hide();
            }
        }
        #endregion

        #region HandleUpdateException
        public void HandleUpdateException()
        {
            MessageBox.Show(@"Wrong data type or this is the non-nullable column! Delete invalid data to reset the cell.", @"SqlException", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
        #endregion

        #region HandleInsertOrUpdate
        public void HandleInsertOrUpdate(string busStopId, string name, string details, string locationN, string locationE, string active)
        {
            var matched = (
                from c in _dc.GetTable<BusStop>()
                where c.busStopId == int.Parse(busStopId)
                select c
                ).SingleOrDefault();

            if (matched == null)
            {
                var busStops = _dc.GetTable<BusStop>();
                var busStop = new BusStop
                {
                    busStopId = short.Parse(busStopId),
                    name = name,
                    details = details,
                    locationN = double.Parse(locationN),
                    locationE = double.Parse(locationE),
                    active = bool.Parse(active)
                };
                busStops.InsertOnSubmit(busStop);
                busStops.Context.SubmitChanges();
            }
            else
            {
                matched.busStopId = short.Parse(busStopId);
                matched.name = name;
                matched.details = details;
                matched.locationN = double.Parse(locationN);
                matched.locationE = double.Parse(locationE);
                matched.active = bool.Parse(active);
                _dc.SubmitChanges();
            }
        }
        #endregion

        #region HandleDelete
        public void HandleDelete(string busStopId)
        {
            var matched = (
                from c in _dc.GetTable<BusStop>()
                where c.busStopId == int.Parse(busStopId)
                select c
                ).SingleOrDefault();

            if (matched != null)
            {
                _dc.BusStops.DeleteOnSubmit(matched);
                _dc.SubmitChanges();
            }
        }
        #endregion

        #region HandleKeyDown
        public void HandleKeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Delete:
                    foreach (DataGridViewRow item in View.dataGridView1.SelectedRows)
                    {
                        try
                        {
                            HandleDelete(item.Cells[0].Value.ToString());
                            View.dataGridView1.Rows.RemoveAt(item.Index);
                        }
                        catch (SqlException)
                        {
                            MessageBox.Show(@"Selected row could not be delete. Check data store integrity. " +
                                            @"Please contact the administrator if this problem persists.",
                                            @"SqlException",
                                            MessageBoxButtons.OK, MessageBoxIcon.Error);

                            _dc = new SearchEngineDatabaseDataContext();
                            LoadData();
                            return;
                        }
                    }
                    break;
            }
        }
        #endregion
    }
}
